//
//  RegisterController.swift
//  注册界面
//
//  Created by smile on 2019/4/6.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

// 导入网络框架
import Moya

//导入响应式编程框架
import RxSwift

//JSON解析为对象
import HandyJSON

class RegisterController: BaseLoginController {

    /// 昵称控件
    @IBOutlet weak var tfNickname: UITextField!
    
    /// 手机号控件
    @IBOutlet weak var tfPhone: UITextField!
    
    /// 邮箱控件
    @IBOutlet weak var tfEmail: UITextField!
    
    
    /// 密码控件
    @IBOutlet weak var tfPassword: UITextField!
    
    
    /// 确认密码控件
    @IBOutlet weak var tfConfirmPassword: UITextField!

    /// 注册按钮
    @IBOutlet weak var btRegister: UIButton!
    
    ///昵称
    var nickname:String?
    
    /// 头像
    var avatar:String?
    
    /// 第三方登录后OpenId
    var openId:String?
    
    /// 登录类型
    var type:SSDKPlatformType?
    
    override func viewDidLoad() {
        super.viewDidLoad()

       }
    
    override func initViews() {
        super.initViews()
        //设置标题
        
        if let _ = openId {
            //如果是第三方登陆
            //就显示补充资料
            //如果还是注册的话
            //用户可能有点懵
            //怎么还要注册
            //不过具体的大家根据业务来实现就行了
            setTitle("补充资料")
            
            //将第三方登陆完成后获取到的昵称
            //设置到昵称输入框
            tfNickname.text=nickname
            
            btRegister.setTitle("完成注册", for: .normal)
            
            //如果第三方登陆就传递过来的信息设置到界面上
            //真实项目中可能还会控制哪些信息是否编译
            
        }else{
            setTitle("注册")
        }
        
//        //设置导航栏标题
//        self.navigationItem.title="注册"
//        
//        //设置导航栏颜色
//        self.navigationController?.navigationBar.tintColor=UIColor.black
        
        //设置圆角
        ViewUtil.showLargeRadius(view: btRegister)
       
        //设置输入框左侧图标
        //真实项目中，会设置为不同的图片
        //这里就不再找相关图片了
        tfNickname.showLeftIcon(name: "LoginItemPhone")
        tfPhone.showLeftIcon(name: "LoginItemPhone")
        tfEmail.showLeftIcon(name: "LoginItemPhone")
        tfPassword.showLeftIcon(name: "LoginItemPhone")
        tfConfirmPassword.showLeftIcon(name: "LoginItemPhone")
        
        //去除返回按钮标题
        self.navigationController!.navigationBar.topItem!.title = ""
    }
    
    
    /// 注册按钮点击事件
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onRegisterClick(_ sender: UIButton) {
//        //请求歌单详情
//        //用来测试网络请求框架
//        let provider = MoyaProvider<Service>()
//        provider.request(.sheetDetail(id: "1")) { result in
//            //result类型是Result<Response, MoyaError>
//            switch result {
//            case let .success(response):
//                //请求成功
//                let data = response.data
//                let code = response.statusCode
//
//                //将data转为String
//                //data的类型为Data
//                let dataString = String(data: data, encoding: String.Encoding.utf8)
//                print("RegisterController request sheet detail succes:\(code),\(dataString)")
//            case let .failure(error):
//                //请求失败
//                print("RegisterController request sheet detail failed:\(error)")
//            }
//        }
        
        //使用RxSwift方式来请求网络
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .subscribe { event in
//                //event类型为SingleEvent<Response>
//                switch event {
//                case let .success(response):
//                    //请求成功
//                    let data = response.data
//                    let code = response.statusCode
//
//                    //将data转为String
//                    //data的类型为Data
//                    let dataString = String(data: data, encoding: String.Encoding.utf8)
//                    print("RegisterController request sheet detail succes:\(code),\(dataString)")
//                case let .error(error):
//                    //请求失败
//                    print("RegisterController request sheet detail failed:\(error)")
//                }
//        }
        
        //将网络请求返回的JSON解析为对象
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .subscribe { event in
//                //event类型为SingleEvent<Response>
//                switch event {
//                case let .success(response):
//                    //请求成功
//                    let data = response.data
//                    let code = response.statusCode
//
//                    //将data转为String
//                    //data的类型为Data
//                    let dataString = String(data: data, encoding: String.Encoding.utf8)
//                    print("RegisterController request sheet detail succes:\(code),\(dataString)")
//
//                    //解析为对象
//                    let sheetWrapper=SheetWrapper.deserialize(from: dataString)
//
//                    //解析完成后打印出歌单详情
//                    print("RegisterController request sheet detail:\(sheetWrapper!.data!.title!)")
//                case let .error(error):
//                    //请求失败
//                    print("RegisterController request sheet detail failed:\(error)")
//                }
//        }
        
        //错误判断
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .subscribe { event in
//                //event类型为SingleEvent<Response>
//                switch event {
//                case let .success(response):
//                    //请求成功
//                    let data = response.data
//                    let code = response.statusCode
//
//                    //将data转为String
//                    //data的类型为Data
//                    let dataString = String(data: data, encoding: String.Encoding.utf8)
//
//                    //404,500这样的错误
//                    //通过这里的code就能判断
//                    print("RegisterController request sheet detail succes:\(code),\(dataString)")
//                case let .error(error):
//                    //将错误类型转为MoyaError
//                    let error = error as! MoyaError
//
//                    //请求失败
//                    print("RegisterController request sheet detail failed:\(error)")
//
//                    //MoyaError是一个枚举
//                    //这样像这样判断
//                    switch error {
//                    case .imageMapping(let response):
//                        print("图片解析错误")
//                        print(response)
//                    case .jsonMapping(let response):
//                        print("JSON解析错误")
//                        print(response)
//                    case .statusCode(let response):
//                        print("状态错误")
//                        print(response)
//                    case .stringMapping(let response):
//                        print("字符串映射错误")
//                        print(response)
//                    case .underlying(let nsError as NSError, let response):
//                        // now can access NSError error.code or whatever
//                        // e.g. NSURLErrorTimedOut or NSURLErrorNotConnectedToInternet
//                        print("这里将错误转为NSNSError：")
//
//                        switch nsError.code {
//                        case NSURLErrorNotConnectedToInternet:
//                            print("网络好像不好，请稍后再试！")
//                        case NSURLErrorTimedOut:
//                            print("连接超时，请稍后再试！")
//
//                            //TODO 更多错误判断可以在这里添加
//                        default:
//                            print("未知错误，请稍后再试！")
//                        }
//
//                        print(nsError.code)
//                        print(nsError.domain)
//                        print(response)
//                    case .requestMapping:
//                        print("请求映射错误")
//                    case .objectMapping(_, _):
//                        print("对象解析错误")
//                    case .encodableMapping(_):
//                        print("对象解析错误")
//                    case .parameterEncoding(_):
//                        print("参数编码错误")
//                    }
//
//
//                }
//
//
//        }
        
//        //日志插件使用方式
//        let provider = MoyaProvider<Service>(plugins:[NetworkLoggerPlugin()])
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .subscribe { event in
//                //event类型为SingleEvent<Response>
//                switch event {
//                case let .success(response):
//                    //请求成功
//                    let data = response.data
//                    let code = response.statusCode
//
//                    //将data转为String
//                    //data的类型为Data
//                    let dataString = String(data: data, encoding: String.Encoding.utf8)
//                    print("RegisterController request sheet detail succes:\(code),\(dataString)")
//
//                case let .error(error):
//                    //请求失败
//                    print("RegisterController request sheet detail failed:\(error)")
//                }
//        }
        
        //请求对话框插件使用方式
//        let provider = MoyaProvider<Service>(plugins:[NetworkActivityPlugin(networkActivityClosure: { (changeType, targetType) in
//            //changeType类型是NetworkActivityChangeType
//            //通过它能监听到开始请求和结束请求
//
//            //targetType类型是TargetType
//            //就是我们这里的service
//            //通过它能判断是那个请求
//
//            if NetworkActivityChangeType.began==changeType{
//                //开始请求
//                print("began request:\(targetType.path)")
//            }else{
//                //结束请求
//                print("end request:\(targetType.path)")
//            }
//
//        })])
        
//        //扩展RxSwift添加解析对象方法
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .asObservable()
//            .mapObject(SheetWrapper.self).subscribe { event in
//                if let data=event.element{
//                    print("JSON解析对象成功：\(data.data?.title)")
//                }
//        }
//
//        扩展RxSwift完成请求详情对象解析
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheetDetail(id: "1"))
//            .asObservable()
//            .mapString()
//            .mapObject(DetailResponse<Sheet>.self)
//            .subscribe(onNext: { data in
//                print("onNext:\(data.data!.title)")
//            }, onError: { error in
//                print("onError:\(error)")
//            }, onCompleted: {
//                print("onCompleted")
//            }) {
//                print("onDisposed")
//        }
        
        //扩展RxSwift完成请求列表对象解析
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheets)
//            .filterSuccessfulStatusCodes()
//            .asObservable()
//            .mapString()
//            .mapObject(ListResponse<Sheet>.self)
//            .subscribe(onNext: { data in
//                print("onNext:\(data.data?.count)")
//            }, onError: { error in
//                print("onError:\(error)")
//            }, onCompleted: {
//                print("onCompleted")
//            }) {
//                print("onDisposed")
//        }
        
        
        //将网络请求具体的信息封装方法中
        //好处是外部直接调用方法传递参数
        //监听结果就行了
        //不需要关系内容使用的是什么框架
        //因为现在很明显我们要直接操作MoyaProvider
        //以及如何使用
        
        //同时还有一些好处
        //例如：在我们项目中获取用户详情的时候
        //可以通过用户id
        //也可以通过用户昵称
        //但如果不在将网络包裹一层
        //假设外部要根据昵称获取用户详情时
        //就需要将用户id传递nil
        //歌单列表
        
        //可以看到封装完毕
        //外部使用的时候
        //不需要知道内部实现
//        Api.shared
//            .sheets()
//            .subscribe(onNext: { data in
//                    print("onNext:\(data.data?.count)")
//                }, onError: { error in
//                    print("onError:\(error)")
//                }, onCompleted: {
//                    print("onCompleted")
//                }) {
//                    print("onDisposed")
//            }
        
        //自动错误处理
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheets)
//            .filterSuccessfulStatusCodes()
//            .asObservable()
//            .mapString()
//            .mapObject(ListResponse<Sheet>.self)
//            .subscribeOnSuccess{ data in
//                print("data:\(data)")
//        }
        
        //手动处理错误
//        let provider = MoyaProvider<Service>()
//        provider
//            .rx
//            .request(.sheets)
//            .filterSuccessfulStatusCodes()
//            .asObservable()
//            .mapString()
//            .mapObject(ListResponse<Sheet>.self)
//            .subscribe({ data in
//                print("onNext:\(data.data?.count)")
//            }) { baseResponse,error  in
//                print("onError:\(error)")
//
//                return true
//        }
//            .subscribe(onNext: { data in
//                    print("onNext:\(data.data?.count)")
//                }, onError: { error in
//                    print("onError:\(error)")
//                }, onCompleted: {
//                    print("onCompleted")
//                }) {
//                    print("onDisposed")
//            }
        
//        就上面的封装
//        大家可能觉得好像和回调没什么区别
//        其实不然
//        使用RxSwift封装后
//        网络请求还能继续变换
//        例如：获取有评论的歌单
//        Api.shared
//            .sheets()
//            .asObservable()
//            .map { data -> ListResponse<Sheet>? in
//                //判断是否有歌单数据
//                if let lists = data.data {
//                    //有歌单
//                    //就直接歌单过滤操作
//                    data.data=lists.filter({ sheet -> Bool in
//                        //返回会true的元素会被选中
//                        //false的元素会被丢弃
//                        return sheet.comments_count > 0
//                    })
//                }
//
//                //返回变换后的数据
//                return data
//            }
//            //TODO 这里还可以进行更多的变换
//            //这里就是Rx响应式编程的好处
//            //他可以将嵌套处理变为一个链式调用
//            .subscribeOnSuccess { data in
//                print("sheets:\(data?.data?.count)")
//        }
        
//        //获取昵称
//        var nickname=tfNickname.text!
//
//        //判断是否输入了昵称
//        //创建一个字符串集
//        let whitespace = NSCharacterSet.whitespacesAndNewlines
//
//        //通过这个方法去除字符串收尾空格和换行
//        nickname=nickname.trimmingCharacters(in: whitespace)
//
//        if nickname.isEmpty {
//            //昵称为空
//            ToastUtil.short("请输入昵称！")
//            return
//        }
//
//        //判断昵称长度是否正确
//        if nickname.count<2 || nickname.count>10 {
//           ToastUtil.short("昵称长度不正确！")
//            return
//        }
//
//        var phone=tfPhone.text!
//
//        //通过这个方法去除字符串收尾空格和换行
//        phone=phone.trimmingCharacters(in: whitespace)
//
//        if phone.isEmpty {
//            //手机号为空
//            ToastUtil.short("请输入手机号！")
//            return
//        }
        
//        使用扩展的方法
//        昵称
        let nickname=tfNickname.text?.trim()!

        if nickname!.isEmpty {
            ToastUtil.short("请输入昵称！")
            return
        }

        guard nickname!.isNickname() else {
           ToastUtil.short("昵称长度不正确！")
            return
        }

        //手机号
        let phone=tfPhone.text!.trim()

        if phone!.isEmpty {
            ToastUtil.short("请手机号！")
            return
        }

        guard phone!.isPhone() else {
           ToastUtil.short("手机号格式不正确！")
            return
        }

        //邮箱
        let email=tfEmail.text!.trim()

        if email!.isEmpty {
            ToastUtil.short("请输入邮箱！")
            return
        }

        guard email!.isEmail() else {
            ToastUtil.short("邮箱格式不正确！")
            return
        }

        //密码
        let password=tfPassword.text!.trim()

        if password!.isEmpty{
            ToastUtil.short("请输入密码！")
            return
        }

        guard password!.isPassword() else {
            ToastUtil.short("密码格式不正确！")
            return
        }

        //确认密码
        let confirmPassword=tfConfirmPassword.text!.trim()

        if confirmPassword!.isEmpty{
            ToastUtil.short("请输入确认密码！")
            return
        }

        guard confirmPassword!.isPassword() else {
           ToastUtil.short("确认密码格式不正确！")
            return
        }

        //确认密码判断
        guard password==confirmPassword else {
            ToastUtil.short("两次密码不正确！")
            return
        }


        //发送注册用户网络请求
        
        //这样要判断类型
        
        var qq_id:String?
        var weibo_id:String?
        
        //不同的登陆，设置到不同的字段
        if SSDKPlatformType.typeQQ==type {
            //QQ第三方登陆
            qq_id=openId
        }else{
            //微博第三方登陆
            weibo_id=openId
        }

        //发送网络请求
        Api.shared
            .createUser(avatar: avatar, nickname: nickname!, phone: phone!, email: email!, password: password!, qq_id: qq_id, weibo_id: weibo_id).subscribe({ data in
                if let data = data?.data{
                    //注册成功
                    AnalysisUtil.onRegister(success:true, avatar: self.avatar, nickname: nickname!, phone: phone!, email: email!, qq_id: qq_id, weibo_id: weibo_id)
                    
                    //注册成功后，直接登陆，是为了给用户更好的体验
                    //当然也可以通过注册接口直接返回
                    //但不太符合接口设计规范
                    //self.login(phone!,password!)
                    
                    //注册用户到聊天服务端
                    //由于注册的时候不能上传头像
                    //所以我们就干脆不让sdk管理任何用户信息
                    //只传递用户名（我们这里传递的是用户Id）
                    
                    //这里不能直接传递密码
                    //因为第三方登陆的时候没有密码
                    //所以如果是第三方登陆
                    //那么就会导致无法登陆聊天服务器
                    //这里我们就简单实现
                    //直接将用户Id当密码
                    //但这样实现其实是有重大Bug
                    //因为用户的Id不会变
                    //真实项目中应该换其他方式实现
                    let id=StringUtil.processUserId(data.id)
                    JMSGUser.register(withUsername: id, password: id, completionHandler: { (data, error) in
                        print("RegisterController message register success")
                        
                        //调用父类的登陆方法
                        self.login(phone:phone,password:password)
                    })
                }else{
                    ToastUtil.short("登陆失败，请稍后再试！")
                }
            }) { (baseResponse, error) -> Bool in
                //注册失败统计
                AnalysisUtil.onRegister(success:false, avatar: self.avatar, nickname: nickname!, phone: phone!, email: email!, qq_id: qq_id, weibo_id: weibo_id)
                
                return false
        }
        
    }
    
    
    /// 用户信息按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onAgreementClick(_ sender: Any) {
        //使用网页控制器打开网页
        WebController.start(self.navigationController!, "用户协议", "http://www.ixuea.com/posts/1")
    }
    
    
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}
